﻿using GameFramework.Event;
using UnityEngine;
using UnityGameFramework.Runtime;
using Utils.Tool.ReadFile;
using Application = UnityEngine.Device.Application;
using GameEntry = Fruits.Base.GameEntry;
using ProcedureOwner = GameFramework.Fsm.IFsm<GameFramework.Procedure.IProcedureManager>;


namespace Fruits.Procedure
{
    public class ProcedureCheckVersion : ProcedureBase
    {
        public override bool UseNativeDialog => true;


        private bool m_CheckVersionComplete = false;
        private bool m_NeedUpdateVersion = false;
        
        private const string ServerUrl = "http://localhost:8080/Version/{0}/VersionInfo.json";
        private const string UpdateInfoUrl = "http://localhost:8080/Version/{0}/UpdateInfo.json";
        private string ApkNetVersion = "1.0.0";
        private long ApkFileSize = 0;

        private float waitTime = 0f;
        private float m_Timer = 0f;
        private bool downloadComplete = false;

        protected override void OnEnter(ProcedureOwner procedureOwner)
        {
            base.OnEnter(procedureOwner);

            m_CheckVersionComplete = false;
            m_NeedUpdateVersion = false;
            
            GameEntry.Event.Subscribe(WebRequestSuccessEventArgs.EventId, OnWebRequestSuccess);
            GameEntry.Event.Subscribe(WebRequestFailureEventArgs.EventId, OnWebRequestFailure);

            //  检查网络连接，没有网络则直接进入游戏
            if (Application.internetReachability == NetworkReachability.NotReachable)
            {
                m_CheckVersionComplete = true;
                m_NeedUpdateVersion = false;
                return;
            }

            //GameEntry.BuiltinData;
            GameEntry.WebRequest.AddWebRequest(UpdateInfoUrl, this);
        }

        protected override void OnUpdate(ProcedureOwner procedureOwner, float elapseSeconds, float realElapseSeconds)
        {
            base.OnUpdate(procedureOwner, elapseSeconds, realElapseSeconds);
              
            //  检查版本未完成，则继续等待
            if (!m_CheckVersionComplete)
                return;
            //  需要更新版本，直接退出游戏
            if (m_NeedUpdateVersion)
            {
                //  没有下载完成则继续等待
                if (!downloadComplete)
                    return;

                //  下载完成等待一段时间后退出游戏
                m_Timer += elapseSeconds;
                if (m_Timer > waitTime)
                    return;
                UnityGameFramework.Runtime.GameEntry.Shutdown(ShutdownType.Quit);
            }
            //  不需要更新版本
            else
            {
                //  去初始化资源
                ChangeState<ProcedureInitResources>(procedureOwner);
            }
        }


        protected override void OnLeave(ProcedureOwner procedureOwner, bool isShutdown)
        {
            GameEntry.Event.Unsubscribe(WebRequestSuccessEventArgs.EventId, OnWebRequestSuccess);
            GameEntry.Event.Unsubscribe(WebRequestFailureEventArgs.EventId, OnWebRequestFailure);
            
            base.OnLeave(procedureOwner, isShutdown);
        }

        private void OnWebRequestSuccess(object sender, GameEventArgs e)
        {
            if (e is not WebRequestSuccessEventArgs ne)
            {
                return;
            }
            
            //  不是当前流程的请求
            if (ne.UserData != this)
                return;


            //  检查版本完成
            m_CheckVersionComplete = true;

            //  解析版本信息
            byte[] versionInfoBytes = ne.GetWebResponseBytes();
            string versionInfoString = GameFramework.Utility.Converter.GetString(versionInfoBytes);

            string[] parts = versionInfoString.Trim().Split(',');
            ApkNetVersion = parts[0].Replace(".", "");
            ApkFileSize = long.Parse(parts[1]);

            //  得到本地版本信息
            string localVersion = ConfigFileOperation.GetString("Version", "0.0.1");
            //  去掉版本号中的点进行对比
            localVersion = localVersion.Replace(".","");

            //  需要强制更新游戏应用
            if (string.Equals(localVersion, ApkNetVersion))
            {
                //  不需要更新版本
                return;
            }


            m_NeedUpdateVersion = true;

            string savePath = string.Format("{0}/{1}{2}.apk", "/sdcard", Application.productName, ApkNetVersion);
            string loadPath = string.Format("{0}/{1}{2}.apk", ServerUrl, Application.productName, ApkNetVersion);


            GameEntry.Event.Subscribe(DownloadStartEventArgs.EventId, OnDownloadStartEvent);
            GameEntry.Event.Subscribe(DownloadUpdateEventArgs.EventId, OnDownloadUpdateEvent);
            GameEntry.Event.Subscribe(DownloadSuccessEventArgs.EventId, OnDownloadSuccessEvent);
            GameEntry.Event.Subscribe(DownloadFailureEventArgs.EventId, OnDownloadFailureEvent);

            GameEntry.Download.AddDownload(savePath, loadPath, this);
        }


        private void OnWebRequestFailure(object sender, GameEventArgs e)
        {
            if (e is not WebRequestFailureEventArgs ne)
            {
                return;
            }
            
            //  不是当前流程的请求
            if (ne.UserData != this)
                return;
            Log.Warning("Check version failure, error message is '{0}'.", ne.ErrorMessage);
        }

        private void OnDownloadStartEvent(object sender, GameEventArgs e)
        {
            if (((DownloadStartEventArgs)e).UserData != this)
            {
                return;
            }
            Log.Info("Download started.");
            GameEntry.BuiltinData.DownloadFormTemplate.SetDownloadInfo(GameEntry.Localization.GetString("StartDownloading"));
        }

        private void OnDownloadUpdateEvent(object sender, GameEventArgs e)
        {
            DownloadStartEventArgs ne = e as DownloadStartEventArgs;
            if (ne.UserData != this)
                return;
            GameEntry.BuiltinData.DownloadFormTemplate.SetDownloadInfo(GameEntry.Localization.GetString("DownloadProgress") +  string.Format("{0}/{1}", GetByteLengthString(ne.CurrentLength), GetByteLengthString(ApkFileSize)));
        }

        private void OnDownloadSuccessEvent(object sender, GameEventArgs e)
        {
            DownloadSuccessEventArgs ne = (DownloadSuccessEventArgs)e;
            if (ne.UserData != this)
            {
                return;
            }

            //  提示下载成功
            GameEntry.BuiltinData.DownloadFormTemplate.SetDownloadInfo(GameEntry.Localization.GetString("DownloadCompleted"));


            GameEntry.Event.Unsubscribe(DownloadStartEventArgs.EventId, OnDownloadStartEvent);
            GameEntry.Event.Unsubscribe(DownloadFailureEventArgs.EventId, OnDownloadFailureEvent);
            GameEntry.Event.Unsubscribe(DownloadSuccessEventArgs.EventId, OnDownloadSuccessEvent);
            GameEntry.Event.Unsubscribe(DownloadUpdateEventArgs.EventId, OnDownloadUpdateEvent);

            //  更新版本信息到sd卡
            string UpdateFilePath = "/sdcard/update.txt";
            string updateInfoStr = "LunPan" + ConfigFileOperation.ReadConfig("VersionInfo", "0.0.1").Replace(".", "") + ",LunPan" + ApkNetVersion;
            System.IO.File.WriteAllText(UpdateFilePath, updateInfoStr);

            //  等待一段时间后退出游戏
            waitTime = 3f;
            m_Timer = 0f;
            downloadComplete = true;
        }


        private void OnDownloadFailureEvent(object sender, GameEventArgs e)
        {
            GameEntry.Event.Unsubscribe(DownloadStartEventArgs.EventId, OnDownloadStartEvent);
            GameEntry.Event.Unsubscribe(DownloadFailureEventArgs.EventId, OnDownloadFailureEvent);
            GameEntry.Event.Unsubscribe(DownloadSuccessEventArgs.EventId, OnDownloadSuccessEvent);
            GameEntry.Event.Unsubscribe(DownloadUpdateEventArgs.EventId, OnDownloadUpdateEvent);
            //  提示下载失败
            GameEntry.BuiltinData.DownloadFormTemplate.SetDownloadInfo(GameEntry.Localization.GetString("DownloadFailed"));
            //UnityGameFramework.Runtime.GameEntry.Shutdown(ShutdownType.Quit);

            waitTime = 3f;
            m_Timer = 0f;
            downloadComplete = true;
        }



        private string GetByteLengthString(long byteLength)
        {
            if (byteLength < 1024L) // 2 ^ 10
            {
                return GameFramework.Utility.Text.Format("{0} Bytes", byteLength);
            }

            if (byteLength < 1048576L) // 2 ^ 20
            {
                return GameFramework.Utility.Text.Format("{0:F2} KB", byteLength / 1024f);
            }

            if (byteLength < 1073741824L) // 2 ^ 30
            {
                return GameFramework.Utility.Text.Format("{0:F2} MB", byteLength / 1048576f);
            }

            if (byteLength < 1099511627776L) // 2 ^ 40
            {
                return GameFramework.Utility.Text.Format("{0:F2} GB", byteLength / 1073741824f);
            }

            if (byteLength < 1125899906842624L) // 2 ^ 50
            {
                return GameFramework.Utility.Text.Format("{0:F2} TB", byteLength / 1099511627776f);
            }

            if (byteLength < 1152921504606846976L) // 2 ^ 60
            {
                return GameFramework.Utility.Text.Format("{0:F2} PB", byteLength / 1125899906842624f);
            }

            return GameFramework.Utility.Text.Format("{0:F2} EB", byteLength / 1152921504606846976f);
        }

    }
}